<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>聚类分析报告 - 数据洞察平台</title>
    <!-- 使用更新的 Plotly.js 版本 -->
    <script src="https://cdn.plot.ly/plotly-2.34.0.min.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.1.3/css/bootstrap.min.css" rel="stylesheet">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.4/css/all.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600&display=swap" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>

    <style>
        :root {
            --primary: #6366f1;
            --secondary: #e0e7ff;
            --success: #10b981;
            --surface: #ffffff;
            --text-primary: #1e293b;
            --highlight: #fde68a;
        }

        body {
            background: var(--secondary);
            font-family: 'Inter', 'PingFang SC', sans-serif;
            line-height: 1.8;
            letter-spacing: 0.02em;
        }

        .report-container {
            max-width: 1400px;
            margin: 2rem auto;
            padding: 2.5rem;
            background: var(--surface);
            border-radius: 1.5rem;
            box-shadow: 0 12px 24px -6px rgba(99, 102, 241, 0.1);
            transform: translateY(0);
            transition: transform 0.3s ease;
        }

        .header-section {
            border-bottom: 2px solid rgba(224, 231, 255, 0.8);
            padding-bottom: 1.5rem;
            margin-bottom: 2rem;
        }

        .cluster-card {
            background: var(--surface);
            border: 1px solid rgba(224, 231, 255, 0.8);
            border-radius: 1rem;
            padding: 1.5rem;
            transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
            opacity: 0;
            transform: translateY(20px);
        }
        .value-pill {
            background-color: var(--secondary);
            border: 1px solid #ddd;
            padding: 0.3rem 0.6rem;
            border-radius: 0.6rem;
            font-size: 0.875rem;
            color: var(--text-primary);
        }

        .cluster-card:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 15px -3px rgba(99, 102, 241, 0.1);
        }

        .chart-wrapper {
            border: 1px solid rgba(224, 231, 255, 0.8);
            border-radius: 1rem;
            margin: 2.5rem 0;
            overflow: hidden;
        }

        #chart-container {
            width: 100%;
            height: 600px;
            min-width: 100%;
            overflow: auto;
            position: relative;
            background: var(--surface);
            border-radius: 1rem;
            margin: 2rem 0;
        }

#chart-container {
    overflow: auto;
    position: relative;
}

#chart-container .plot-container {
    width: 100% !important;
    height: 100% !important;
}

#chart-container .plotly-graph-div {
    width: 100% !important;
    height: 100% !important;
    display: flex;
    justify-content: center;
    align-items: center;
}

        .ai-section {
            margin-top: 3rem;
            position: relative;
        }

        .ai-generate-btn {
            background: linear-gradient(135deg, var(--success), #059669);
            padding: 1rem 2.5rem;
            border-radius: 2rem;
            font-weight: 600;
            letter-spacing: 0.05em;
            transition: all 0.3s ease;
            position: relative;
            overflow: hidden;
        }

        .ai-generate-btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 10px 20px rgba(16, 185, 129, 0.2);
        }

        .loading-indicator {
            display: none;
            align-items: center;
            gap: 1rem;
            color: var(--primary);
        }

        .spinner {
            width: 28px;
            height: 28px;
            border: 3px solid rgba(99, 102, 241, 0.1);
            border-top-color: var(--primary);
            animation: spin 0.8s linear infinite;
        }

        #ai-report {
            background: rgba(255, 255, 255, 0.95);
            backdrop-filter: blur(8px);
            border-radius: 1rem;
            margin-top: 2rem;
            transition: all 0.3s ease;
        }

        .report-content {
            font-size: 1rem;
            color: var(--text-primary);
        }

        .report-content h5 {
            color: var(--primary);
            margin: 1.5rem 0 1rem;
            padding-bottom: 0.5rem;
            border-bottom: 2px solid var(--primary);
        }

        .report-content li {
            position: relative;
            padding-left: 1.5rem;
            margin-bottom: 0.75rem;
        }

        .report-content li::before {
            content: '▹';
            position: absolute;
            left: 0;
            color: var(--success);
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        #analysis-result {
            opacity: 0;
            transform: translateY(20px);
            transition: all 0.6s cubic-bezier(0.34, 1.56, 0.64, 1);
            pointer-events: none;
        }
        #analysis-result.show {
            opacity: 1;
            transform: translateY(0);
            pointer-events: auto;
        }
        .progress {
            border-radius: 14px;
            overflow: hidden;
            background-color: var(--secondary);
            box-shadow: inset 0 2px 4px rgba(0,0,0,0.05);
        }
        #confidence-bar {
            transition: width 0.8s cubic-bezier(0.4, 0, 0.2, 1) !important;
        }
        .user-analysis-section .cluster-avatar {
            position: relative;
            width: 80px;
            height: 80px;
            margin: 0 auto;
            background: var(--secondary);
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
        }
        .cluster-id-badge {
            position: absolute;
            right: -10px;
            bottom: -5px;
            background: var(--success);
            color: white;
            width: 28px;
            height: 28px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            font-size: 14px;
            font-weight: bold;
        }
        .toast-notification {
            position: fixed;
            bottom: 2rem;
            right: 2rem;
            background: white;
            padding: 1rem 1.5rem;
            border-radius: 12px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.15);
            display: flex;
            align-items: center;
            gap: 1rem;
            z-index: 9999;
        }
        .toast-icon {
            width: 8px;
            height: 8px;
            border-radius: 50%;
        }
    </style>
</head>
<body>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>

    <div class="report-container">
        <header class="header-section">
            <div class="d-flex justify-content-between align-items-center mb-4">
                <h1 class="h3 mb-0">
                    <i class="fas fa-chart-network me-2" style="color: var(--primary)"></i>
                    数据聚类洞察报告
                </h1>
                <a href="/" class="btn btn-primary px-4 py-2">
                    <i class="fas fa-arrow-left me-2"></i>返回控制台
                </a>
            </div>

            <div class="d-flex gap-3">
                <div class="badge bg-primary-subtle text-primary py-2 px-3">
                    <i class="fas fa-database me-2"></i>{{ filename }}
                </div>
                <div class="badge bg-primary-subtle text-primary py-2 px-3">
                    <i class="fas fa-cubes me-2"></i>{{ cluster_centers|length }} 个聚类模式
                </div>
            </div>
        </header>

        <section class="mb-5">
            {% load custom_filters %}
            <h3 class="h5 mb-4">
                <i class="fas fa-project-diagram me-2"></i>各类用户特征：详细解释点击<b>智能分析报告</b>
            </h3>
            <div class="row g-4">
                {% for center in cluster_centers %}
                <div class="col-12 col-md-6 col-lg-4">
                    <div class="cluster-card">
                        <div class="d-flex justify-content-between align-items-center mb-3">
                            <span class="fw-bold text-primary"
                                  data-bs-toggle="tooltip"
                                  data-bs-placement="top"
                                  title="{{ cluster_descriptions|get_item:forloop.counter0 }}">
                                用户类别 {{ forloop.counter }}
                            </span>
                            <span class="badge bg-success-subtle text-success">
                                维度 {{ center|length }}
                            </span>
                        </div>
                        <div class="d-flex flex-wrap gap-2">
                            {% for val in center %}
                            <div class="value-pill">
                                {{ val|floatformat:2 }}
                            </div>
                            {% endfor %}
                        </div>
                    </div>
                </div>
                {% endfor %}
            </div>
        </section>

        <div class="chart-wrapper position-relative">
            <div class="chart-header d-flex justify-content-between align-items-center p-4 bg-light">
                <h3 class="h5 mb-0">
                    <i class="fas fa-chart-network me-2"></i>不同用户类别下各属性的分布情况
                </h3>
                <div class="chart-controls">
                    <button class="btn btn-sm btn-outline-primary zoom-in">
                        <i class="fas fa-search-plus"></i>
                    </button>
                    <button class="btn btn-sm btn-outline-primary zoom-out">
                        <i class="fas fa-search-minus"></i>
                    </button>
                </div>
            </div>
            <div style="max-height: 700px; overflow-y: auto; border: 1px solid #ccc; padding: 10px;">
                {{ chart_html|safe }}
            </div>
        </div>

        <section class="ai-section">
            <button id="ai-generate-btn" class="ai-generate-btn text-white border-0">
                <i class="fas fa-magic me-2"></i>生成智能分析报告
            </button>
            <div class="loading-indicator mt-3">
                <div class="spinner"></div>
                <span>深度分析中，预计需要12秒...</span>
            </div>

            <div id="ai-report" class="mt-4 p-4">
                <div class="d-flex justify-content-between align-items-center mb-3">
                    <h4 class="mb-0">
                        <i class="fas fa-file-certificate me-2"></i>分析报告
                    </h4>
                    <div class="btn-group">
                        <button class="btn btn-sm btn-outline-primary" onclick="copyReport()">
                            <i class="far fa-copy me-2"></i>复制
                        </button>
                        <button class="btn btn-sm btn-outline-primary" onclick="exportReport()">
                            <i class="fas fa-download me-2"></i>导出
                        </button>
                    </div>
                </div>
                <div id="report-content" class="report-content"></div>
            </div>
        </section>
    </div>

    <section class="user-analysis-section mt-5">
        <div class="card border-primary">
            <div class="card-header bg-primary text-white">
                <h4 class="mb-0">
                    <i class="fas fa-user-secret me-2"></i>
                    用户群体分析器
                </h4>
            </div>
            <div class="card-body">
                <div class="input-group">
                    <textarea id="user-input"
                        class="form-control"
                        placeholder="请输入用户评论（支持中英文，建议50-200字）..."
                        rows="3"></textarea>
                    <button id="analyze-btn"
                        class="btn btn-success">
                        <i class="fas fa-brain me-2"></i>智能分析
                    </button>
                </div>
                <div class="form-text text-muted mt-2">
                    🧹 <strong>提示：</strong>请分享您对扫地机器人的真实看法或使用体验。以下是一些参考示例：
                    <ul class="small text-muted mt-1 mb-0 ps-3">
                        <li>✅ 我的扫地机器人能定时清扫，噪音小，非常适合有小孩的家庭。</li>
                        <li>✅ 它导航挺精准的，就是容易卡在茶几下面。</li>
                        <li>✅ 买回来两个月了，用得不多，主要是家里太乱，机器人发挥不出作用。</li>
                        <li>❌ 不建议输入：“不错”、“可以”、“还行” 这种太简略的词。</li>
                    </ul>
                </div>
                <div id="analysis-result" class="mt-4 p-3 bg-white rounded-3 shadow-sm" style="display:none;">
                    <div class="row align-items-center g-4">
                        <div class="col-12 col-md-3 text-center">
                            <div class="cluster-avatar position-relative">
                                <i class="fas fa-user fa-3x text-primary"></i>
                                <span class="cluster-id-badge position-absolute top-0 start-100 translate-middle">
                                    <span id="cluster-id">0</span>
                                </span>
                            </div>
                        </div>
                        <div class="col-12 col-md-9">
                            <h5 class="mb-3">用户分析结果：
                                <span id="cluster-name" class="text-primary">分析中...</span>
                            </h5>

                            <div class="progress-container mb-4">
                                <div id="confidence-header" class="mb-2"></div>
                                <div class="progress" style="height: 12px; border-radius: 6px;">
                                    <div id="confidence-bar"
                                        class="progress-bar"
                                        role="progressbar"
                                        style="width: 0%;">
                                    </div>
                                </div>
                            </div>

                            <div id="cluster-features" class="alert alert-light">
                                <h6 class="alert-heading"><i class="fas fa-fingerprint me-2"></i>用户关键特征</h6>
                                <ul id="feature-list" class="mb-0"></ul>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <script>
        let isAnalyzing = false;
        let isInitialized = false;
        let resizeTimeout;

        function initCoreModules() {
            if (isInitialized) return;

            document.querySelectorAll('.cluster-card').forEach((card, index) => {
                setTimeout(() => {
                    card.style.opacity = 1;
                    card.style.transform = 'translateY(0)';
                }, 150 * index);
            });
                // 初始化 tooltip
            document.querySelectorAll('[data-bs-toggle="tooltip"]').forEach(el => {
                new bootstrap.Tooltip(el);
            });

            window.addEventListener('resize', () => {
                clearTimeout(resizeTimeout);
                resizeTimeout = setTimeout(resizeChart, 200);
            });

            const initConfidenceHeader = () => {
                const headerContainer = document.getElementById('confidence-header');
                if (!headerContainer) return;

                if (!headerContainer.querySelector('#confidence-label')) {
                    headerContainer.innerHTML = `
                        <div class="d-flex justify-content-between small text-muted mb-2">
                            <span id="confidence-label">匹配置信度</span>
                            <span id="confidence-text">0%</span>
                        </div>
                    `;
                }
            };
            initConfidenceHeader();

            isInitialized = true;
        }

        function safeUpdateResult(data) {
            try {
                const elements = {
                    clusterId: document.querySelector('#cluster-id'),
                    clusterName: document.querySelector('#cluster-name'),
                    confidenceBar: document.querySelector('#confidence-bar'),
                    confidenceText: document.querySelector('#confidence-text'),
                    featureList: document.querySelector('#feature-list'),
                    avatar: document.querySelector('.cluster-avatar')
                };

                Object.entries(elements).forEach(([key, element]) => {
                    if (!element) throw new Error(`找不到元素: ${key}`);
                });

                console.log('Updating result with data:', data);

                const validData = {
                    cluster_id: data.cluster_id || 0,
                    cluster_name: data.cluster_name || '未知类别',
                    confidence: Math.min(Math.max(data.confidence || 0, 0), 1),
                    color: data.color || '#6366f1',
                    icon: data.icon || 'fa-user',
                    key_features: Array.isArray(data.key_features) && data.key_features.length > 0 ? data.key_features : ['暂无特征']
                };

                gsap.killTweensOf(elements.confidenceBar);
                gsap.killTweensOf(elements.confidenceText);

                const clusterNumber = validData.cluster_id;
                elements.clusterId.textContent = clusterNumber;
                elements.clusterName.textContent = validData.cluster_name;
                elements.clusterName.style.color = validData.color;

                const confidencePercent = Math.round(validData.confidence * 100);
                gsap.to(elements.confidenceBar, {
                    width: `${confidencePercent}%`,
                    backgroundColor: validData.color,
                    duration: 1.2,
                    onUpdate: () => {
                        const currentWidth = parseFloat(elements.confidenceBar.style.width) || 0;
                        elements.confidenceText.textContent = `${Math.round(currentWidth)}%`;
                    }
                });

                elements.featureList.innerHTML = validData.key_features
                    .map(f => `
                        <li class="mb-2" style="color: ${validData.color}">
                            <i class="fas fa-circle-small me-2"></i>${f}
                        </li>`
                    )
                    .join('');

                elements.avatar.innerHTML = '';
                const icon = document.createElement('i');
                icon.className = `fas ${validData.icon} fa-3x`;
                icon.style.color = validData.color;

                const badge = document.createElement('span');
                badge.className = 'cluster-id-badge';
                badge.style.background = validData.color;
                badge.textContent = clusterNumber;

                elements.avatar.appendChild(icon);
                elements.avatar.appendChild(badge);

            } catch (error) {
                console.error('结果更新失败:', error);
                showToast('结果更新失败，请重试', 'danger');
            }
        }

        async function handleAnalysis() {
            if (isAnalyzing) return;
            isAnalyzing = true;

            const input = document.getElementById('user-input').value.trim();
            const resultContainer = document.getElementById('analysis-result');

            try {
                if (!input) {
                    showToast('请输入要分析的文本内容', 'warning');
                    return;
                }
                if (input.length < 20 || input.length > 1000) {
                    showToast('输入长度需在20-1000字符之间', 'danger');
                    return;
                }

                resultContainer.style.opacity = 0;
                resultContainer.style.transform = 'translateY(20px)';
                toggleAnalyzeButton(true);

                const response = await fetch('/api/analyze-user-group/', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json',
                        'X-CSRFToken': getCookie('csrftoken')
                    },
                    body: JSON.stringify({
                        text: input,
                        lang: 'zh-CN'
                    })
                });

                if (!response.ok) throw new Error(`请求失败: ${response.status}`);
                const responseData = await response.json();
                console.log('Received response:', responseData);

                if (responseData.status !== 'success') {
                    throw new Error(responseData.message || '分析失败');
                }

                const analysisData = responseData.data;
                if (!analysisData) {
                    throw new Error('响应中未包含分析数据');
                }

                gsap.to(resultContainer, {
                    opacity: 1,
                    y: 0,
                    duration: 0.6,
                    ease: "power2.out",
                    onStart: () => resultContainer.style.display = 'block',
                    onComplete: () => safeUpdateResult(analysisData)
                });

            } catch (error) {
                console.error('分析失败:', error);
                showToast(`分析失败: ${error.message}`, 'danger');
            } finally {
                isAnalyzing = false;
                toggleAnalyzeButton(false);
            }
        }

        function toggleAnalyzeButton(loading) {
            const btn = document.getElementById('analyze-btn');
            btn.disabled = loading;
            btn.innerHTML = loading ?
                `<div class="spinner-border spinner-border-sm me-2"></div>分析中...` :
                `<i class="fas fa-brain me-2"></i>智能分析`;
        }

        function showToast(message, type = 'info') {
            const colors = {
                info: '#6366f1',
                success: '#10b981',
                warning: '#f59e0b',
                danger: '#ef4444'
            };

            const toast = document.createElement('div');
            toast.className = `toast-notification`;
            toast.innerHTML = `
                <div class="toast-icon" style="background: ${colors[type]}"></div>
                <span>${message}</span>
            `;

            document.body.appendChild(toast);

            gsap.fromTo(toast,
                { x: 100, opacity: 0 },
                { x: 0, opacity: 1, duration: 0.3, ease: "power2.out" }
            );

            setTimeout(() => {
                gsap.to(toast, {
                    opacity: 0,
                    y: -20,
                    onComplete: () => toast.remove(),
                    duration: 0.3
                });
            }, 3000);
        }

        function getCookie(name) {
            let cookieValue = null;
            if (document.cookie && document.cookie !== '') {
                const cookies = document.cookie.split(';');
                for (let i = 0; i < cookies.length; i++) {
                    const cookie = cookies[i].trim();
                    if (cookie.substring(0, name.length + 1) === (name + '=')) {
                        cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                        break;
                    }
                }
            }
            return cookieValue;
        }

        function resizeChart() {
            const chart = document.getElementById('chart-container');
            if (chart && window.Plotly) {
                Plotly.Plots.resize(chart);
            }
        }

        document.addEventListener('DOMContentLoaded', () => {
            initCoreModules();

            const analyzeBtn = document.getElementById('analyze-btn');
            if (!analyzeBtn._hasListener) {
                analyzeBtn.addEventListener('click', handleAnalysis);
                analyzeBtn._hasListener = true;
            }

            const generateBtn = document.getElementById('ai-generate-btn');
            const loadingIndicator = document.querySelector('.loading-indicator');
            const reportContent = document.getElementById('report-content');

            if (!generateBtn._hasListener) {
                generateBtn.addEventListener('click', async function() {
                    const button = this;
                    const startTime = Date.now();

                    try {
                        button.disabled = true;
                        loadingIndicator.style.display = 'flex';
                        reportContent.innerHTML = '';

                        const response = await fetch('/api/generate-report/', {
                            method: 'POST',
                            headers: {
                                'Content-Type': 'application/json',
                                'X-CSRFToken': getCookie('csrftoken')
                            },
                            body: JSON.stringify({
                                clusters: {{ cluster_centers|safe }},
                                metadata: {
                                    filename: "{{ filename }}",
                                    dimensions: {{ cluster_centers.0|length }}
                                }
                            })
                        });

                        if (!response.ok) throw new Error(`HTTP错误! 状态码: ${response.status}`);

                        const data = await response.json();

                        const minLoadTime = 1200;
                        const elapsed = Date.now() - startTime;
                        if (elapsed < minLoadTime) {
                            await new Promise(resolve =>
                                setTimeout(resolve, minLoadTime - elapsed)
                            );
                        }

                        gsap.fromTo(reportContent,
                            { opacity: 0, y: 20 },
                            {
                                opacity: 1,
                                y: 0,
                                duration: 0.6,
                                ease: "power2.out",
                                onStart: () => {
                                    reportContent.innerHTML = data.report
                                        .replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
                                        .replace(/- (.*?)(\n|$)/g, '<li>$1</li>');
                                }
                            }
                        );

                    } catch (error) {
                        console.error('报告生成失败:', error);
                        showToast(`报告生成失败: ${error.message}`, 'danger');
                        reportContent.innerHTML = `
                            <div class="alert alert-danger">
                                <i class="fas fa-exclamation-triangle me-2"></i>
                                报告生成失败：${error.message}
                            </div>
                        `;
                    } finally {
                        button.disabled = false;
                        loadingIndicator.style.display = 'none';
                    }
                });
                generateBtn._hasListener = true;
            }

        });

        function exportReport() {
            try {
                const content = document.getElementById('report-content');
                if (!content) throw new Error('找不到报告内容');

                const blob = new Blob([content.innerText], {
                    type: 'text/plain; charset=UTF-8'
                });

                const url = URL.createObjectURL(blob);
                const link = document.createElement('a');
                link.href = url;
                link.download = `聚类分析报告_${new Date().toISOString().slice(0,10)}.txt`;
                document.body.appendChild(link);
                link.click();

                setTimeout(() => {
                    document.body.removeChild(link);
                    URL.revokeObjectURL(url);
                }, 100);

                showToast('报告已成功导出', 'success');
            } catch (error) {
                console.error('导出失败:', error);
                showToast(`导出失败: ${error.message}`, 'danger');
            }
        }

        function copyReport() {
    try {
        const content = document.getElementById('report-content');
        if (!content) throw new Error('找不到报告内容');

        const text = content.innerText;

        // 创建临时 textarea 元素
        const textArea = document.createElement('textarea');
        textArea.value = text;
        textArea.style.position = 'fixed'; // 避免影响页面布局
        textArea.style.opacity = '0'; // 隐藏元素
        document.body.appendChild(textArea);
        textArea.focus();
        textArea.select();

        try {
            const successful = document.execCommand('copy');
            if (successful) {
                showToast('报告已复制到剪贴板', 'success');
            } else {
                throw new Error('复制失败');
            }
        } catch (err) {
            throw new Error('复制失败');
        } finally {
            document.body.removeChild(textArea);
        }
    } catch (error) {
        console.error('复制失败:', error);
        showToast(`复制失败: ${error.message}`, 'danger');
    }
}
    </script>
</body>
</html>